package com.tengju.user.infrastructure.repository;

import com.google.common.collect.Lists;
import com.tengju.user.domain.model.survey.*;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.SurveyConfigDO;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.SurveyContentDO;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.SurveyMetaDO;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.SurveyConfigDOCustomMapper;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.SurveyContentDOCustomMapper;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.SurveyMetaDOCustomMapper;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.generate.SurveyConfigDOMapper;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.generate.SurveyMetaDOMapper;
import com.tengju.user.infrastructure.repository.convert.SurveyConfigConvert;
import com.tengju.user.infrastructure.repository.convert.SurveyConvert;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

@Repository
public class SurveyRepotioryImpl implements SurveyRepotiory {

    @Resource
    SurveyConfigDOCustomMapper surveyConfigDOCustomMapper;

    @Resource
    SurveyConfigDOMapper surveyConfigDOMapper;

    @Resource
    SurveyContentDOCustomMapper surveyContentDOCustomMapper;

    @Resource
    SurveyMetaDOCustomMapper surveyMetaDOCustomMapper;

    @Resource
    SurveyMetaDOMapper surveyMetaDOMapper;

    @Override
    public SurveyConfig getConfigById(Long surveyId) {
        SurveyMetaDO surveyMetaDO = surveyMetaDOMapper.selectByPrimaryKey(surveyId);
        if (surveyMetaDO == null) {
            return null;
        }
        List<SurveyConfigDO> surveyConfigDOList = surveyConfigDOCustomMapper.listBySurveyId(surveyId);
        SurveyMeta surveyMeta = SurveyConvert.convertMetaDOToEntity(surveyMetaDO);
        List<SurveyQuestionConfig> surveyQuestionConfigList = surveyConfigDOList.stream()
                .map(SurveyConvert::convertQuestionConfigDOListToEntity)
                .collect(Collectors.toList());
        return SurveyFactory.createSurveyConfig(surveyMeta, surveyQuestionConfigList);
    }

    @Override
    public SurveyMeta getMetaById(Long surveyId) {
        SurveyMetaDO surveyMetaDO = surveyMetaDOMapper.selectByPrimaryKey(surveyId);
        if (surveyMetaDO == null) {
            return null;
        }
        return SurveyConvert.convertMetaDOToEntity(surveyMetaDO);
    }

    @Override
    public SurveyId getIdByTitle(String title) {
        SurveyMetaDO surveyMetaDO = surveyMetaDOCustomMapper.queryByTitle(title);
        if (surveyMetaDO == null || surveyMetaDO.getId() == null) {
            return null;
        }
        return new SurveyId(surveyMetaDO.getId());
    }

    @Override
    @Transactional(value = "dealerTransactionManager", rollbackFor = Exception.class)
    public Boolean saveSurveyContent(SurveyContent surveyContent) {
        List<SurveyContentDO> surveyContentDOList = SurveyConvert.convertContentToDOs(surveyContent);
        surveyContentDOCustomMapper.batchinsert(surveyContentDOList);
        return true;
    }

    @Override
    public Boolean isSubmitByIdCodeSurveyId(UserIdCode idCode, Long surveyId) {
        return surveyContentDOCustomMapper.isSubmitByIdCodeSurveyId(idCode.getValue(), surveyId);
    }

    @Override
    public SurveyContent getContent(UserIdCode idCode, SurveyId surveyId) {

        List<SurveyContentDO> surveyContentDOList = surveyContentDOCustomMapper
                .queryByIdCodeSurveyId(idCode.getValue(), surveyId.getValue());

        if (CollectionUtils.isEmpty(surveyContentDOList)) {
            return null;
        }

        List<SurveyConfigDO> surveyConfigDOList = surveyConfigDOCustomMapper.listBySurveyId(surveyId.getValue());
        Map<String, SurveyConfigDO> surveyConfigDOMap = surveyConfigDOList.stream()
                .collect(Collectors.toMap(SurveyConfigDO::getItemCode, Function.identity()));


        ArrayList<SurveyQuestionResult> resultList = Lists.newArrayList();

        for (SurveyContentDO surveyContentDO: surveyContentDOList) {

            SurveyConfigDO surveyConfigDO = surveyConfigDOMap.get(surveyContentDO.getItemCode());

            SurveyQuestionResult result = new SurveyQuestionResult(
                    Optional.ofNullable(surveyConfigDO).map(SurveyConfigDO::getItemOrder).orElse(null),
                    surveyContentDO.getItemCode(),
                    Optional.ofNullable(surveyConfigDO).map(SurveyConfigDO::getItemTitle).orElse(null),
                    surveyContentDO.getItemContent(),
                    Optional.ofNullable(surveyConfigDO).map(SurveyConfigDO::getQueryTitle).orElse(null));

            resultList.add(result);
        }

        return new SurveyContent(idCode,surveyId,resultList);

    }

    @Override
    public Boolean saveSurveyConfig(SurveyConfigInfo surveyConfigInfo) {
        SurveyConfigDO surveyConfigDO = SurveyConfigConvert.convertToDO(null,surveyConfigInfo);
        surveyConfigDOMapper.insert(surveyConfigDO);
        return true;
    }

    @Override
    public Boolean updateSurveyConfig(Long id, SurveyConfigInfo surveyConfigInfo) {
        SurveyConfigDO surveyConfigDO = SurveyConfigConvert.convertToDO(id,surveyConfigInfo);
        surveyConfigDOMapper.updateByPrimaryKeySelective(surveyConfigDO);
        return true;
    }
}
